﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

namespace WC
{
    namespace Net
    {
        public class NetStatistics
        {
            private NetStatistics() { }
            public NetStatistics(string name)
            {
                _name = name;
            }
            public void SetName(string name)
            {
                _name = name;
            }
            public uint TimeSpan
            {
                get
                {
                    TimeSpan ts = new TimeSpan(DateTime.Now.Ticks - _beginTime.Ticks);
                    return (uint)Math.Abs(ts.TotalSeconds);
                }
            }
            public void Print(log4net.ILog log)
            {
                log.WarnFormat("------------------------------------------------------");
                log.WarnFormat("[{0}] _accepted = {1:#,##0}", _name, _accepted);
                log.WarnFormat("[{0}] _connect = {1:#,##0}", _name, _connect);
                log.WarnFormat("[{0}] _connected = {1:#,##0}", _name, _connected);
                log.WarnFormat("[{0}] _closed = {1:#,##0}\n", _name, _closed);

                log.WarnFormat("[{0}] _send_packets = {1:#,##0}", _name, _send_packets);
                log.WarnFormat("[{0}] _sent_packets = {1:#,##0}", _name, _sent_packets);
                log.WarnFormat("[{0}] _rcvd_packets = {1:#,##0}\n", _name, _rcvd_packets);

                log.WarnFormat("[{0}] _send_size = {1:#,##0} MB", _name, _send_size/1024/1024);
                log.WarnFormat("[{0}] _sent_size = {1:#,##0} MB", _name, _sent_size/1024/1024);
                log.WarnFormat("[{0}] _rcvd_size = {1:#,##0} MB\n", _name, _rcvd_size/1024/1024);

                log.WarnFormat("[{0}] throughput._send_packets = {1:#,##0} /s", _name, _send_packets / TimeSpan);
                log.WarnFormat("[{0}] throughput._sent_packets = {1:#,##0} /s", _name, _sent_packets / TimeSpan);
                log.WarnFormat("[{0}] throughput._rcvd_packets = {1:#,##0} /s\n", _name, _rcvd_packets / TimeSpan);

                log.WarnFormat("[{0}] throughput._send_size = {1:#,##0} KB/s", _name, _send_size / 1024 / TimeSpan);
                log.WarnFormat("[{0}] throughput._sent_size = {1:#,##0} KB/s", _name, _sent_size / 1024 / TimeSpan);
                log.WarnFormat("[{0}] throughput._rcvd_size = {1:#,##0} KB/s\n", _name, _rcvd_size / 1024 / TimeSpan);

                log.WarnFormat("[{0}] _link_constructor = {1:#,##0}", _name, _link_constructor);
                log.WarnFormat("[{0}] _link_disposed = {1:#,##0}", _name, _link_disposed);
                log.WarnFormat("[{0}] _link_destructor = {1:#,##0}", _name, _link_destructor);
                log.WarnFormat("------------------------------------------------------");
            }

            public void OnAccepted(Object sender, Object newlink)
            {
                System.Threading.Interlocked.Increment(ref _accepted);
            }
            public void OnReceived(Object sender, byte[] buffer, int size)
            {
                Debug.Assert(0 != size);
                System.Threading.Interlocked.Increment(ref _rcvd_packets);
                lock (this)
                {
                    _rcvd_size += (ulong)size;
                }
            }
            public void OnSent(Object sender, byte[] buffer, int size, Object state)
            {
                Debug.Assert(0 != size);
                System.Threading.Interlocked.Increment(ref _sent_packets);
                lock (this)
                {
                    _sent_size += (ulong)size;
                }
            }
            public void OnClosed(Object sender)
            {
                System.Threading.Interlocked.Increment(ref _closed);
            }
            public void SendPacket(int size)
            {
                System.Threading.Interlocked.Increment(ref _send_packets);
                lock (this)
                {
                    _send_size += (ulong)size;
                }
            }
            public void TryConnect()
            {
                System.Threading.Interlocked.Increment(ref _connect);
            }
            public void Connected()
            {
                System.Threading.Interlocked.Increment(ref _connected);
            }
            public void link_constructor()
            {
                System.Threading.Interlocked.Increment(ref _link_constructor);
            }
            public void link_destructor()
            {
                System.Threading.Interlocked.Increment(ref _link_destructor);
            }
            public void link_disposed()
            {
                System.Threading.Interlocked.Increment(ref _link_destructor);
            }

            private string _name = "Unknown";

            private int _accepted;
            private int _connect;
            private int _connected;
            private int _closed;

            private int _send_packets;
            private ulong _send_size;

            private int _sent_packets;
            private ulong _sent_size;

            private int _rcvd_packets;
            private ulong _rcvd_size;

            public int _link_constructor;
            public int _link_destructor;
            public int _link_disposed;

            public DateTime _beginTime = DateTime.Now;
        }
    }
}
